﻿using Kimd.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Serialization;

namespace Kimd.Motion
{
    [Serializable]
    public class Sensor : ICsv
    {
        private short _bitNo;
        private Dictionary<int, int> cardNo2Count;
        private ControlCard _card;
        [XmlIgnore]
        public ControlCard Card
        {
            get { return _card; }
            set { _card = value; }
        }
        public string Description { get; set; }
        public string ControlCardName { get; set; }
        public bool AlwaysOn { get; set; }
        public string Module { get; set; }
        private string _id;
        public string ID
        {
            get { return _id; }
            set 
            { 
                _id = value;
                if (cardNo2Count != null && !string.IsNullOrEmpty(_id))
                {
                    int index = 0;
                    foreach (var item in cardNo2Count)
                    {
                        if (item.Key.Equals(Convert.ToInt32(_id.Split('_')[0])))
                        {
                            index += Convert.ToInt32(_id.Split('_')[2].Substring(2));
                            break;
                        }
                        else
                        {
                            index += item.Value;
                        }
                    }
                    _bitNo = (short)index;
                }
            }
        }

        public SerializableDictionary<string, string> CsvName2Property { get; set; }

        [XmlIgnore]
        public List<string> CardConfig 
        {
            set
            {
                cardNo2Count = new Dictionary<int, int>();
                if (value != null)
                {
                    foreach (var item in value)
                    {
                        if (item.Split('_')[1].Equals("DI8") ||
                            item.Split('_')[1].Equals("DI16") ||
                            item.Split('_')[1].Equals("DI32"))
                        {
                            cardNo2Count.Add(Convert.ToInt32(item.Split('_')[0]), Convert.ToInt32(item.Split('_')[1].Substring(2)));
                        }
                        if (item.Split('_')[1].Equals("DIO8") ||
                            item.Split('_')[1].Equals("DIO16") ||
                            item.Split('_')[1].Equals("DIO32"))
                        {
                            cardNo2Count.Add(Convert.ToInt32(item.Split('_')[0]), Convert.ToInt32(item.Split('_')[1].Substring(3)));
                        }
                    }
                    ID = _id;
                }
            }
        }
        public Sensor()
        {
            CsvName2Property = new SerializableDictionary<string, string>();
            CsvName2Property.Add("名称", nameof(Description));
            CsvName2Property.Add("所属模组", nameof(Module));
            CsvName2Property.Add("所属轴卡", nameof(ControlCardName));
            CsvName2Property.Add("ID", nameof(ID));
        }
        public Sensor(string name)
            : this()
        {
            this.Description = name;
        }
        public Sensor(string name, string cardName, string id, bool alwaysOn, string moduleName)
            : this(name)
        {
            this.ControlCardName = cardName;
            this.ID = id;
            this.AlwaysOn = alwaysOn;
            this.Module = moduleName;
        }

        public bool WaitOn(int waitTime = 0, bool onOff = true)
        {
            if (_card == null)
                return false;
            if (!AlwaysOn)
            {
                if (waitTime == 0 && onOff)
                {
                    return _card.DigitalOperator.GetInBitStatus(Card.CardNo, _bitNo);
                }
                else if (waitTime == 0 && !onOff)
                {
                    return !_card.DigitalOperator.GetInBitStatus(Card.CardNo, _bitNo);
                }
                else if (onOff)
                {
                    DateTime dtnow = DateTime.Now;
                    while (!_card.DigitalOperator.GetInBitStatus(Card.CardNo, _bitNo))
                    {
                        TimeSpan ts = DateTime.Now - dtnow;
                        if (ts.Milliseconds + ts.Seconds * 1000 > waitTime)
                        {
                            //MachineMessageScheduler.Instance.Add(new MachineMessage(ExceptionType.NormalError, string.Format("等待感应器ON{0}超时!", Description), "Sensor", 0));
                            return false;
                        }
                        Thread.Sleep(2);
                    }
                    return true;
                }
                else
                {
                    DateTime dtnow = DateTime.Now;
                    while (_card.DigitalOperator.GetInBitStatus(Card.CardNo, _bitNo))
                    {
                        TimeSpan ts = DateTime.Now - dtnow;
                        if (ts.Milliseconds + ts.Seconds * 1000 > waitTime)
                        {
                            //MachineMessageScheduler.Instance.Add(new MachineMessage(ExceptionType.NormalError, string.Format("等待感应器OFF{0}超时!", Description), "Sensor", 0));
                            return false;
                        }
                        Thread.Sleep(2);
                    }
                    return true;
                }
            }
            else
            {
                if (waitTime == 0 && onOff)
                    return !_card.DigitalOperator.GetInBitStatus(Card.CardNo, _bitNo);
                else if (waitTime == 0 && !onOff)
                    return _card.DigitalOperator.GetInBitStatus(Card.CardNo, _bitNo);
                else if (onOff)
                {
                    DateTime dtnow = DateTime.Now;
                    while (_card.DigitalOperator.GetInBitStatus(Card.CardNo, _bitNo))
                    {
                        TimeSpan ts = DateTime.Now - dtnow;
                        if (ts.Milliseconds + ts.Seconds * 1000 > waitTime)
                        {
                            //MachineMessageScheduler.Instance.Add(new MachineMessage(ExceptionType.NormalError, string.Format("等待感应器OFF{0}超时!", Description), "Sensor", 0));
                            return false;
                        }
                        Thread.Sleep(2);
                    }
                    return true;
                }
                else
                {
                    DateTime dtnow = DateTime.Now;
                    while (!_card.DigitalOperator.GetInBitStatus(Card.CardNo, _bitNo))
                    {
                        TimeSpan ts = DateTime.Now - dtnow;
                        if (ts.Milliseconds + ts.Seconds * 1000 > waitTime)
                        {
                            //MachineMessageScheduler.Instance.Add(new MachineMessage(ExceptionType.NormalError, string.Format("等待感应器ON{0}超时!", Description), "Sensor", 0));
                            return false;
                        }
                        Thread.Sleep(2);
                    }
                    return true;
                }
            }
        }
    }
}
